package com.huidu.bitrade.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huidu.bitrade.constant.TransactionType;
import com.huidu.bitrade.entity.AcNodeHdz;
import com.huidu.bitrade.entity.MemberWallet;
import com.huidu.bitrade.entity.OtcCoin;
import com.huidu.bitrade.mapper.AcMemberMapper;
import com.huidu.bitrade.entity.AcMember;
import com.huidu.bitrade.entity.transform.AuthMember;
import com.huidu.bitrade.enums.MemberStarEnum;
import com.huidu.bitrade.service.AcNodeHdzService;
import com.huidu.bitrade.service.LocaleMessageSourceService;
import com.huidu.bitrade.service.MemberWalletService;
import com.huidu.bitrade.service.PurchasePayService;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;

/**
 * 币本位
 */
@Service("HdzPurchaseService")
@AllArgsConstructor
public class HdzPurchasePayServiceImpl implements PurchasePayService {


    @Autowired
    private AcMemberMapper acMemberMapper;
    @Autowired
    private MemberWalletService memberWalletService;
    @Autowired
    private LocaleMessageSourceService msService;
    @Autowired
    private AcNodeHdzService acNodeHdzService;

    private final BigDecimal HDZ_PERCENTAGE = BigDecimal.valueOf(0.7);

    @Override
    public boolean purchase(Integer payType, AuthMember authMember, MemberStarEnum starEnum, Integer purchaseCount, String batchCode, BigDecimal currentHdz) {
        //获得账户余额
        OtcCoin otcCoin = new OtcCoin();
        otcCoin.setUnit("HDZ");
        MemberWallet walletHdc = memberWalletService.findByOtcCoinAndMemberId(otcCoin, authMember.getId());
        Assert.isTrue(Objects.nonNull(walletHdc),msService.getMessage("HDZ_NO_ACCOUNT"));
        //查询用户购买节点专用hdz
        AcNodeHdz acNodeHdz = acNodeHdzService.getOne(Wrappers.<AcNodeHdz>lambdaQuery().eq(AcNodeHdz::getMemberId,walletHdc.getMemberId()));
        BigDecimal hdcBalance = walletHdc.getBalance();
        if(Objects.nonNull(acNodeHdz)){
            hdcBalance = hdcBalance.add(acNodeHdz.getHdz());
        }
        //计算所有hdz
        Data data = calculate(authMember, starEnum,hdcBalance);
        acMemberMapper.insert(AcMember.builder()
                .batchCode(batchCode)
                .memberId(authMember.getId())
//                .count(starEnum.getCount())
                .count(purchaseCount)
                .currentHdz(currentHdz)
                .memberStar(starEnum.getLevel())
                .payType(payType)
                .type("HDZ")
                .before(hdcBalance)
                .number(data.getUseHDZ())
                .quantity(data.hdz)
                .after(hdcBalance.subtract(data.hdz))
                .percentage(HDZ_PERCENTAGE)
                .build());
        BigDecimal hdz = data.hdz;
        if(Objects.nonNull(acNodeHdz)){
            if(acNodeHdz.getHdz().compareTo(hdz)>=0){
                //如果专用hdz足够，直接扣除专用hdz
                acNodeHdz.setHdz(acNodeHdz.getHdz().subtract(hdz).setScale(8, RoundingMode.DOWN));
                return acNodeHdzService.updateById(acNodeHdz);
            }else{
                //如果专用hdz不够，扣完之后剩余扣除hdz钱包余额
                hdz = hdz.subtract(acNodeHdz.getHdz()).setScale(8,RoundingMode.DOWN);
                acNodeHdz.setHdz(BigDecimal.ZERO);
                acNodeHdzService.updateById(acNodeHdz);
            }
        }
        //减少钱包余额,记录交易流水
        return memberWalletService.operateDeductBalance(walletHdc,hdz, TransactionType.ROUTING_BUY);
    }

    @Override
    public void purchaseImport(Integer payType, AuthMember authMember, MemberStarEnum starEnum, Integer purchaseCount, String batchCode, BigDecimal currentHdz){
        //获得账户余额
        BigDecimal hdcBalance = BigDecimal.ZERO;
        //计算所有hdz
        Data data = calculate(authMember, starEnum,BigDecimal.valueOf(99999));
        acMemberMapper.insert(AcMember.builder()
                .batchCode(batchCode)
                .memberId(authMember.getId())
//                .count(starEnum.getCount())
                .count(purchaseCount)
                .currentHdz(currentHdz)
                .memberStar(starEnum.getLevel())
                .payType(payType)
                .type("HDZ")
                .before(hdcBalance)
                .number(data.getUseHDZ())
                .quantity(data.hdz)
                .after(hdcBalance.subtract(data.hdz))
                .percentage(HDZ_PERCENTAGE)
                .build());
    }

    private Data calculate(AuthMember authMember, MemberStarEnum starEnum,BigDecimal hdcBalance){
        //用户需要购买的星级减去当前星级hdz = 本次需要购买的星级所需hdz
        MemberStarEnum currentStar = authMember.getMemberStarEnum();
        BigDecimal useHDZ = starEnum.getHdz();
        if(null != currentStar){
            useHDZ = starEnum.getHdz().subtract(currentStar.getHdz());
        }
        BigDecimal hdz = useHDZ.multiply(HDZ_PERCENTAGE);
        Assert.isTrue(hdcBalance.compareTo(hdz) >= 0,msService.getMessage("HDZ_INSUFFICIENT_ACCOUNT_BALANCE"));
        return Data.builder()
                .hdz(hdz)
                .useHDZ(useHDZ)
                .build();
    }

    @lombok.Data
    @Builder
    static class Data{
        private BigDecimal useHDZ;
        private BigDecimal hdz;
    }

}
